import { getProfileById } from '@/api/profile'
import { getToolID } from '@/api/tool'

export default class MemoryBus {
  constructor(user_id) {
    // user_id : 用户的 ID,用于获取 Profile INT
    this.user_id = user_id
    this.memory = {}
  }

  // 刷新 MemoryBus
  async refresh(taskList) {
    console.log('用于生成 memoryBus 的 taskList', taskList)
    await getProfileById(this.user_id).then(res => {
      //  point1：获取 Profile，每次修改后都重新获取一遍，保证是最新的
      const form = {}
      if (res.length === 1) {
        Object.keys(res[0]).forEach(key => {
          if (key !== 'user_id') {
            form[key] = {
              description: res[0][key],
              value: ''
            }
          }
        })
      } else {
        Object.keys(res[0]).forEach(key => {
          if (key !== 'user_id') {
            form[key] = {
              description: res[0][key],
              value: res[1][key] ? res[1][key] : ''
            }
          }
        })
      }
      // console.log('------', form)
      this.memory['Profile'] = JSON.parse(JSON.stringify(form))
    })
    for (const key of Object.keys(taskList)) {
      const task = 'Task' + (Number(key) + 1)
      // point2: 为每个子任务注册单独的 memoryBus
      this.memory[task] = {}
      // point3: 保存用户在这次应用创建过程中的 InputVar
      if ('parameters' in taskList[key]) {
        this.memory[task]['InputVar'] = {}
        const params = taskList[key]['parameters']
        for (const param of params) {
          if (param.sourceType === 'input') {
            // console.log('检测到一个 input', param)
            if ('defaultValue' in param['sourceData']['option']) {
              this.memory[task]['InputVar'][param['sourceData']['option']['variableName']] = param['sourceData']['option']['defaultValue']
            } else {
              this.memory[task]['InputVar'][param['sourceData']['option']['variableName']] = ''
            }
          }
        }
        if (Object.keys(this.memory[task]['InputVar']).length === 0 &&
          this.memory[task]['InputVar'].constructor === Object) {
          delete this.memory[task].InputVar
        }
      }
      // point4：正则匹配每个子任务的前、后置代码，获取写在代码中的条目
      this.memory[task]['PreCodeVar'] = {}
      this.memory[task]['PostCodeVar'] = {}
      const regex = /memory_bus\.add\("([^"]+)",([^)]+?)\)/g
      let match
      //   后置代码
      while ((match = regex.exec(taskList[key]['post_code'])) !== null) {
        // console.log('匹配到了一个 codeVar', match)
        if (match[1] !== 'your_key') {
          this.memory[task]['PostCodeVar'][match[1]] = match[2]
        }
      }
      //   前置代码
      while ((match = regex.exec(taskList[key]['pre_code'])) !== null) {
        // console.log('匹配到了一个 codeVar', match)
        if (match[1] !== 'your_key') {
          this.memory[task]['PreCodeVar'][match[1]] = match[2]
        }
      }
      if (Object.keys(this.memory[task]['PreCodeVar']).length === 0 &&
        this.memory[task]['PreCodeVar'].constructor === Object) {
        delete this.memory[task].PreCodeVar
      }
      if (Object.keys(this.memory[task]['PostCodeVar']).length === 0 &&
        this.memory[task]['PostCodeVar'].constructor === Object) {
        delete this.memory[task].PostCodeVar
      }
      // point5：获取每个工具的 outputStructure，作为 Refer 类型
      if ('tool_id' in taskList[key]) {
        await getToolID(taskList[key].tool_id).then(response => {
          // 将数据结构加载进MemoryBus中
          if (response.output_structure !== null &&
            typeof response.output_structure === 'object' &&
            Object.keys(response.output_structure).length > 0) {
            this.memory[task]['Refer'] = JSON.parse(JSON.stringify(response.output_structure))
          }
        })
      }
      // 清空没有选择任务的工具
      if (Object.keys(this.memory[task]).length === 0 &&
        this.memory[task].constructor === Object) {
        delete this.memory.task
      }
    }
    console.log('构建好的 memoryBus', this.memory)
    // point5：完成 memoryBus 的刷新
    return true
  }

  // 获取 task (index+1) 能够看到的 memoryBus
  // pos 即为哪个位置的组件获取 memoryBus，0 则为前置代码，1 则为工具，2 则为后置代码
  getMemory(index, pos = 1) {
    const allocatedMemoryBus = {}
    // 第一步 直接分配 Profile（都能看到）
    if (this.memory.Profile) {
      allocatedMemoryBus['profile'] = this.memory.Profile
    } else {
      console.log('MemoryBus 中不存在 Profile', this.memory)
    }
    // 第二步 合成出 inputVar
    index = Number(index) + 1
    // console.log('index 的值为: ', index)
    allocatedMemoryBus['inputVar'] = {}
    // 工具和后置代码能够利用当前工具的 inputVar
    if (pos && 'InputVar' in this.memory['Task' + Number(index)]) {
      allocatedMemoryBus['inputVar'] = {
        ...allocatedMemoryBus['inputVar'], // 保留原有的
        ...this.memory['Task' + Number(index)]['InputVar'] // 插入新的
      }
    }
    for (let i = 1; i < index; i++) {
      if ('InputVar' in this.memory['Task' + Number(i)]) {
        allocatedMemoryBus['inputVar'] = {
          ...allocatedMemoryBus['inputVar'], // 保留原有的
          ...this.memory['Task' + Number(i)]['InputVar'] // 插入新的
        }
      }
    }
    if (Object.keys(allocatedMemoryBus['inputVar']).length === 0 &&
      allocatedMemoryBus['inputVar'].constructor === Object) {
      delete allocatedMemoryBus.inputVar
    }
    // 第三步 合成出 codeVar
    // 首先合并后置 codeVar
    allocatedMemoryBus['codeVar'] = {}
    for (let i = 1; i < index; i++) {
      if ('PostCodeVar' in this.memory['Task' + Number(i)]) {
        allocatedMemoryBus['codeVar'] = {
          ...allocatedMemoryBus['codeVar'], // 保留原有的
          ...this.memory['Task' + Number(i)]['PostCodeVar'] // 插入新的
        }
      }
    }
    // 然后合并前置 codeVar
    for (let i = 1; i < index; i++) {
      if ('PreCodeVar' in this.memory['Task' + Number(i)]) {
        allocatedMemoryBus['codeVar'] = {
          ...allocatedMemoryBus['codeVar'], // 保留原有的
          ...this.memory['Task' + Number(i)]['PreCodeVar'] // 插入新的
        }
      }
    }
    // 后置代码能看到当前任务前置代码的 codeVar
    if (pos > 1 && 'PreCodeVar' in this.memory['Task' + Number(index)]) {
      allocatedMemoryBus['codeVar'] = {
        ...allocatedMemoryBus['codeVar'], // 保留原有的
        ...this.memory['Task' + Number(index)]['PreCodeVar'] // 插入新的
      }
    }
    if (Object.keys(allocatedMemoryBus['codeVar']).length === 0 &&
      allocatedMemoryBus['codeVar'].constructor === Object) {
      delete allocatedMemoryBus.codeVar
    }
    // 第四步 分离出所有能看到的 refer
    for (let i = 1; i < index; i++) {
      if ('Refer' in this.memory['Task' + Number(i)]) {
        allocatedMemoryBus['task' + Number(i)] = { ...this.memory['Task' + Number(i)]['Refer'] } // 展开运算符
      }
    }
    // 后置代码能够看到当前工具的输出
    if (pos > 1) {
      allocatedMemoryBus['task' + Number(index)] = { ...this.memory['Task' + Number(index)]['Refer'] }
    }
    return allocatedMemoryBus
  }
}
